dnl
dnl hidrd/usage/all.h template.
dnl
dnl Copyright (C) 2010 Nikolai Kondrashov
dnl
dnl This file is part of hidrd.
dnl
dnl Hidrd is free software; you can redistribute it and/or modify
dnl it under the terms of the GNU General Public License as published by
dnl the Free Software Foundation; either version 2 of the License, or
dnl (at your option) any later version.
dnl
dnl Hidrd is distributed in the hope that it will be useful,
dnl but WITHOUT ANY WARRANTY; without even the implied warranty of
dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
dnl GNU General Public License for more details.
dnl
dnl You should have received a copy of the GNU General Public License
dnl along with hidrd; if not, write to the Free Software
dnl Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
dnl
include(`m4/hidrd/util.m4')dnl
dnl
`/*
 * vim:nomodifiable
 *
 * ************* DO NOT EDIT **************
 * This file is autogenerated from all.h.m4
 * ****************************************
 */
/** @file
 * @brief HID report descriptor - all usages
 *
 * Copyright (C) 2010 Nikolai Kondrashov
 *
 * This file is part of hidrd.
 *
 * Hidrd is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * Hidrd is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with hidrd; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 *
 * @author Nikolai Kondrashov <spbnick@gmail.com>
 */

#ifndef __HIDRD_USAGE_ALL_H__
#define __HIDRD_USAGE_ALL_H__

#include "hidrd/cfg.h"
#include "hidrd/util/num.h"
#include "hidrd/usage/page.h"
#include "hidrd/usage/id.h"
#include "hidrd/usage/type.h"

#ifdef __cplusplus
extern "C" {
#endif

typedef enum hidrd_usage {
#define _U(_page, _id) (((HIDRD_USAGE_PAGE_##_page) << 16) | (_id))

    HIDRD_USAGE_UNDEFINED = _U(UNDEFINED, 0x0000U),

'pushdef(`PAGE',
`ifelse(eval(PAGE_ID_NUM(`$2') > 0), 1,
`pushdef(`ID',
`    /** capitalize_first('$`4) ('$`3) */
    HIDRD_USAGE_`'uppercase($2)_`'uppercase('$`2) = _PU(0x'$`1U),
')dnl
    /*
     * capitalize_first(`$3') page
     */
`#'define _PU(_id) _U(uppercase(`$2'), _id)

sinclude(`db/usage/id_'lowercase($2)`.m4')dnl

#undef _PU

popdef(`ID')dnl
')')dnl
include(`db/usage/page.m4')dnl
popdef(`PAGE')dnl
`     /*
     * Vendor-defined page FFFF (last possible)
     */
#define _PU(_id) _U(VENDOR_FFFF, _id)

    /** Usage FFFF (last possible) */
    HIDRD_USAGE_VENDOR_FFFF_FFFF = _PU(0xFFFFU)

#undef _PU

#undef _U
} hidrd_usage;

#define HIDRD_USAGE_MIN HIDRD_USAGE_UNDEFINED
#define HIDRD_USAGE_MAX HIDRD_USAGE_VENDOR_FFFF_FFFF

/**
 * Check if a usage is valid.
 *
 * @param usage Usage to check.
 *
 * @return True if usage is valid, false otherwise.
 */
extern bool hidrd_usage_valid(hidrd_usage usage);

/**
 * Check if a usage is known, in effect, if there is a description for it.
 *
 * @param usage Usage to check.
 *
 * @return True if the usage is known, false otherwise.
 */
extern bool hidrd_usage_known(hidrd_usage usage);

/* Declare usage to string conversion functions */
HIDRD_NUM_CONV_DECLS(usage);

/**
 * Retrieve usage page from a usage.
 *
 * @param usage Usage to retrieve usage page from.
 *
 * @return Usage page.
 */
static inline hidrd_usage_page
hidrd_usage_get_page(hidrd_usage usage)
{
    assert(hidrd_usage_valid(usage));
    return (usage >> 16) & UINT16_MAX;
}


/**
 * Check if a usage has defined page.
 *
 * @param usage Usage to check.
 *
 * @return True if the usage has defined page, false otherwise.
 */
static inline bool
hidrd_usage_defined_page(hidrd_usage usage)
{
    assert(hidrd_usage_valid(usage));
    return hidrd_usage_page_defined(hidrd_usage_get_page(usage));
}


/**
 * Set usage page.
 *
 * @param usage Usage to set page to.
 * @param page  Usage page to set.
 *
 * @return Usage with modified page.
 */
static inline hidrd_usage
hidrd_usage_set_page(hidrd_usage usage, hidrd_usage_page page)
{
    assert(hidrd_usage_valid(usage));
    assert(hidrd_usage_page_valid(page));
    return (usage & UINT16_MAX) | (page << 16);
}


/**
 * Retrieve usage ID from a usage.
 *
 * @param usage Usage to retrieve usage ID from.
 *
 * @return Usage ID.
 */
static inline hidrd_usage_id
hidrd_usage_get_id(hidrd_usage usage)
{
    assert(hidrd_usage_valid(usage));
    return usage & UINT16_MAX;
}


/**
 * Set usage ID.
 *
 * @param usage Usage to set ID to.
 * @param page  Usage ID to set.
 *
 * @return Usage with modified ID.
 */
static inline hidrd_usage
hidrd_usage_set_id(hidrd_usage usage, hidrd_usage_id id)
{
    assert(hidrd_usage_valid(usage));
    assert(hidrd_usage_id_valid(id));
    return (usage & (UINT16_MAX << 16)) | id;
}


/**
 * Compose a new usage from usage page and ID.
 *
 * @param page  Usage page.
 * @param id    Usage ID.
 *
 * @return New usage.
 */
static inline hidrd_usage
hidrd_usage_compose(hidrd_usage_page page, hidrd_usage_id id)
{
    assert(hidrd_usage_page_valid(page));
    assert(hidrd_usage_id_valid(id));
    return (page << 16) | id;
}


/**
 * Check if a usage is top-level (in effect, if its ID is top-level).
 *
 * @param usage Usage to check.
 *
 * @return True if the usage is top-level, false otherwise.
 */
static inline bool
hidrd_usage_top_level(hidrd_usage usage)
{
    assert(hidrd_usage_valid(usage));
    return hidrd_usage_id_top_level(hidrd_usage_get_id(usage));
}


#ifdef HIDRD_WITH_TOKENS
/**
 * Convert a usage to a string token.
 *
 * @param usage Usage.
 *
 * @return Dynamically allocated usage token, or NULL if no token was found
 *         or failed to allocate memory (check errno for the latter).
 */
extern char *hidrd_usage_to_token(hidrd_usage usage);


/**
 * Convert a usage to a ID token string.
 *
 * @param usage Usage.
 *
 * @return Dynamically allocated usage ID token, or NULL if no token was
 *         found or failed to allocate memory (check errno for the latter).
 */
extern char *hidrd_usage_to_id_token(hidrd_usage usage);


/**
 * Convert a string token to a usage.
 *
 * @param pusage    Location for usage; will not be modified in case of
 *                  error; could be NULL.
 * @param token     String token.
 *
 * @return True if token is found, false otherwise.
 */
extern bool hidrd_usage_from_token(hidrd_usage *pusage,
                                   const char  *token);

#endif /* HIDRD_WITH_TOKENS */

#ifdef HIDRD_WITH_NAMES

/**
 * Retrieve usage ID name string (close to specification).
 *
 * @param usage Usage code.
 *
 * @return Usage ID name string, or NULL if not found.
 */
extern const char *hidrd_usage_id_name(hidrd_usage usage);

#ifdef HIDRD_WITH_TOKENS

/**
 * Format description of usage ID as used in particular usage.
 *
 * @param usage Usage code to generate ID description for.
 *
 * @return Dynamically allocated usage ID description, or NULL if failed to
 *         allocate memory; could be an empty string, if there is nothing to
 *         tell about the usage ID.
 */
extern char *hidrd_usage_desc_id_str(hidrd_usage usage);

/**
 * Format usage description.
 *
 * @param usage Usage code to generate description for.
 *
 * @return Dynamically allocated usage description, or NULL if failed to
 *         allocate memory; could be an empty string, if there is nothing to
 *         tell about the usage.
 */
extern char *hidrd_usage_desc_str(hidrd_usage usage);

#endif /* HIDRD_WITH_TOKENS */

#endif /* HIDRD_WITH_NAMES */

#ifdef __cplusplus
} /* extern "C" */
#endif

#endif /* __HIDRD_USAGE_ALL_H__ */
'dnl
